#include "inc/crc16_modbus.h"

CRC16Modbus::CRC16Modbus()
{
    m_name = "CRC16/Modbus";
    m_pascal = "x16 + x15 + x2 + 1";
    m_poly = 0x8005;
    m_init = 0xFFFF;
    m_xorout = 0x00;
    m_refin = true;
    m_refout = true;
}

uint64_t CRC16Modbus::crcCalc(const uint8_t *data, int64_t len)
{
    if (NULL == data) {
        return -1;
    }
    if (len <= 0) {
        return -1;
    }

    uint16_t crc = 0xFFFF;
    uint32_t i = 0;
    uint8_t ch;

    static uint16_t crc_talbe[] =
    {
        0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
        0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,
    };

    for (i = 0; i < len; i++)
    {
        ch = *data++;
        crc = crc_talbe[(ch ^ crc) & 15] ^ (crc >> 4);
        crc = crc_talbe[((ch >> 4) ^ crc) & 15] ^ (crc >> 4);
    }

    return crc;
}
